#ifndef ALGA_AMD_ATOMBIOS_VM_H
#define ALGA_AMD_ATOMBIOS_VM_H
/*
  author Sylvain Bertrand <sylvain.bertrand@gmail.com>
  Protected by linux GNU GPLv2
  Copyright 2012-2014
*/
#define ATB_DONT_HAVE_VDDC_CTL	0
#define ATB_HAVE_VDDC_CTL	1
long atb_have_vddc_ctl(struct atombios *atb);

#define ATB_DONT_HAVE_MVDDC_CTL	0
#define ATB_HAVE_MVDDC_CTL	1
long atb_have_mvddc_ctl(struct atombios *atb);

#define ATB_DONT_HAVE_VDDCI_CTL	0
#define ATB_HAVE_VDDCI_CTL	1
long atb_have_vddci_ctl(struct atombios *atb);

#define ATB_DONT_HAVE_VDDC_PHASE_SHED_CTL	0
#define ATB_HAVE_VDDC_PHASE_SHED_CTL		1
long atb_have_vddc_phase_shed_ctl(struct atombios *atb);

/*----------------------------------------------------------------------------*/
struct atb_volt_tbl_entry {
	u32 smio_low;
	u16 val_mv; /* XXX: mV units or phase shed thingy */
};

#define ATB_VOLT_TBL_ENTRIES_N_MAX 32
struct atb_volt_tbl {
	u8 entries_n;
	u8 phase_delay;
	u32 mask_low;
	struct atb_volt_tbl_entry entries[ATB_VOLT_TBL_ENTRIES_N_MAX];
};
long atb_vddc_tbl_get(struct atombios *atb, struct atb_volt_tbl *tbl);
long atb_mvddc_tbl_get(struct atombios *atb, struct atb_volt_tbl *tbl);
long atb_vddci_tbl_get(struct atombios *atb, struct atb_volt_tbl *tbl);
long atb_vddc_phase_shed_tbl_get(struct atombios *atb,
						struct atb_volt_tbl *tbl);
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
struct atb_volt_on_clk_dep {
	u32 clk;
	u16 volt_id;	/* XXX: can be a lkge idx or mV units */
};
struct atb_volt_on_clk_dep_tbl {
	u8 entries_n;
	struct atb_volt_on_clk_dep *entries;
};
long atb_vddc_dep_on_sclk_tbl_get(struct atombios *atb,
					struct atb_volt_on_clk_dep_tbl *tbl);
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
struct atb_cac_lkge {
	u16 vddc_mv;	/* XXX: only mV units here */
	u32 lkge;
};
struct atb_cac_lkge_tbl {
	u8 entries_n;
	struct atb_cac_lkge *entries;
};
long atb_cac_lkge_tbl_get(struct atombios *atb, struct atb_cac_lkge_tbl *tbl);
/*----------------------------------------------------------------------------*/

long atb_cac_lkge_get(struct atombios *atb, u32 *cac_lkge);
long atb_load_line_slope_get(struct atombios *atb, u16 *load_line_slope);

/*----------------------------------------------------------------------------*/
struct atb_vddc_phase_shed_limits {
	u16 vddc_mv;
	u32 sclk;
	u32 mclk;
};

struct atb_vddc_phase_shed_limits_tbl {
	u8 entries_n;
	struct atb_vddc_phase_shed_limits *entries;
};

long atb_vddc_phase_shed_limits_tbl_get(struct atombios *atb,
				struct atb_vddc_phase_shed_limits_tbl *tbl);
/*----------------------------------------------------------------------------*/

long atb_pp_volt_time_get(struct atombios *atb, u16 *volt_time);
#endif
